package com.pudu.mydemo.view;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathEffect;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.pudu.mydemo.utils.PointToLineDis;
import com.pudutech.pdrobot.R;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

/**
 * TODO: document your custom view class.
 */
public class MapBuildView extends SurfaceView implements SurfaceHolder.Callback{

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        if(null == mDrawThread) {
            mDrawThread = new DrawThread();
            mDrawThread.start();

            Canvas canvas = holder.lockCanvas();
            DrawUseSurface(canvas);
            holder.unlockCanvasAndPost(canvas);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        if(null != mDrawThread) {
            mDrawThread.exit();
            mDrawThread = null;
        }

        if( mBmpBackground_map.isRecycled()==false )
        {
            mBmpBackground_map.recycle();
        }
    }

    public MapBuildView(Context context) {
        super(context);
        init();
    }

    public MapBuildView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public MapBuildView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        nWidth = MeasureSpec.getSize(widthMeasureSpec);
        nHeight = MeasureSpec.getSize(heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public void init()
    {
        initLinePaint();

        initAlllinesePaint();

        initDotLinesPaint();

        initBackgroundPaint();

        initMapLinePaint();

        InitMapData();

        mHolder = this.getHolder();
        mHolder.addCallback(this);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        nHeight = h;
        nWidth = w;
    }

    Map<String, Bitmap> map = new HashMap<String, Bitmap>();

    public static final int MSG_INVALIDATE = 0;
    private Handler mHandler;
    SurfaceHolder mHolder;
    private DrawThread mDrawThread;
    private Looper mLooper;

    class DrawThread extends Thread {
        @Override
        public void run() {
            Looper.prepare();

            mLooper = Looper.myLooper();

            mHandler = new Handler(){
                public void handleMessage (Message msg) {
                    switch(msg.what) {
                        case MSG_INVALIDATE: {
                            Canvas canvas = null;

                            try {
                                if (null != mHolder) {
                                    canvas = mHolder.lockCanvas();
                                    DrawUseSurface(canvas);
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                            } finally {
                                if (null != mHolder) {
                                    try {
                                        mHolder.unlockCanvasAndPost(canvas);
                                    }catch(Exception e)
                                    {
                                        e.printStackTrace();
                                    }
                                }
                            }
                            break;
                        }
                    }
                }
            };

            Looper.loop();
        }

        public void exit() {
            if (mLooper != null) {
                mLooper.quit();
                mLooper = null;
            }
        }
    }

    public void DrawUseSurface(Canvas canvas)
    {
        canvas.drawColor(Color.argb(255, 204,204,204));
        DrawbkMap(canvas);

        if( nWorkMode != 4) {

            DrawOriginPoint(canvas, nWidth / 2 + xOriginShift, nHeight / 2 + yOriginShift);
            DrawBackgroundLine(canvas);
        }

        DrawDotLinesMap(canvas);

        if(nWorkMode == 8 ) {
            if (bBeginDraw_DotLines) {
                DrawAttachLine_Dotlines(canvas);
            }
        }

        DrawBackgroundMap(canvas);

        DrawAllLinesMap(canvas);


        if(nWorkMode == 0 ) {
            if (bBeginDraw_bk) {
                DrawAttachLine_bk(canvas);
            }
        }

        if(nWorkMode == 6 ) {
            if (bBeginDraw_AllLines) {
                DrawAttachLine_Alllines(canvas);
            }
        }


        if(nWorkMode == 2 ) {
            if (bBeginDraw_mapline) {
                DrawAttachLine_mapline(canvas);
            }
        }

        DrawCurrentLineMap(canvas);
    }

    public void DrawbkMap(Canvas canvas)
    {
        Rect src = new Rect();
        Rect dst = new Rect();
        src.top = 0;
        src.left = 0;
        src.right = mBmpBackground_map.getWidth();
        src.bottom = mBmpBackground_map.getHeight();

        dst.top = 0;
        dst.left = 0;
        dst.right = nWidth;
        dst.bottom = nHeight;

        Paint vPaint = new Paint();
        vPaint.setAlpha( 255 );

        canvas.drawBitmap(mBmpBackground_map, src, dst, vPaint);
    }

    public int GetWorkMode()
    {
        return nWorkMode;
    }

    public void SetWorkMode(int nMode)
    {
        nWorkMode = nMode;

        if(nMode == 5)
        {
            resetAllData();
            nWorkMode = 0;
        }

        if(mHandler != null)
         mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    public void InitMapData()
    {
        mapLineIndex = 0;

        if( mjsonString.isEmpty() == false)
        {
            LoadMap(mjsonString);
        }
        else {
            jsonBackground = new JSONArray();
            jsonMapModul = new JSONArray();
            jsonAlllines = new JSONArray();
            jsonDotLines = new JSONArray();
            jsonMap = new JSONObject();

            try {

                JSONObject mymaps = new JSONObject();
                JSONArray maplinns = new JSONArray();
                mymaps.put("Map", maplinns);

                jsonMapModul.put(mymaps);

                jsonMap.put("Background", jsonBackground);
                jsonMap.put("MapModules", jsonMapModul);
                jsonMap.put("AllLines", jsonAlllines);
                jsonMap.put("DotLines", jsonDotLines);

                Log.i("aaaa", jsonMap.toString());

            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }

    String mjsonString = "";
    public void LoadMap(String map)
    {
        mjsonString = map;
        try {
            jsonMap = new JSONObject(map);
            jsonMapModul = jsonMap.getJSONArray("MapModules");
            jsonBackground = jsonMap.getJSONArray("Background");
            jsonAlllines = jsonMap.getJSONArray("AllLines");
            jsonDotLines = jsonMap.getJSONArray("DotLines");
            jsonMapinfo = jsonMap.getJSONObject("Mapinfo");

            linexSeparation = jsonMapinfo.getInt("linexSeparation");
            lineySeparation = jsonMapinfo.getInt("lineySeparation");

            xOriginShift = jsonMapinfo.getInt("xOriginShift");
            yOriginShift = jsonMapinfo.getInt("yOriginShift");

            if(mHandler!= null)
            {
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            Log.i("aaaa", jsonMap.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public String GetMap()
    {
        JSONObject jsonMapinfo = new JSONObject();
        try {
            Log.i("aaaa", "scale:" + scale);
            jsonMapinfo.put("linexSeparation", linexSeparation);
            jsonMapinfo.put("lineySeparation", lineySeparation);
            jsonMapinfo.put("xOriginShift", xOriginShift);
            jsonMapinfo.put("yOriginShift", yOriginShift);

            jsonMap.put("Mapinfo", jsonMapinfo);

        } catch (JSONException e) {
            e.printStackTrace();
        }


        return jsonMap.toString();
    }

    public void delMapbyIndex(int nIndex)
    {
        if(nIndex >= GetMapSize())
        {
            return;
        }

        if(nIndex == 0 && GetMapSize() == 1)
        {
            return;
        }

        try {
            jsonMapModul = jsonMap.getJSONArray("MapModules");
            JSONArray jsonMapModulNew = new JSONArray();

            int nLen = jsonMapModul.length();
            for(int i = 0; i < nLen; i ++)
            {
                if(i != mapLineIndex)
                {
                    JSONObject obj = jsonMapModul.getJSONObject(i);
                    jsonMapModulNew.put(obj);
                }
                else
                {
                    continue;
                }
            }

            jsonMap.put("MapModules", jsonMapModulNew);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void AddNewMap()
    {
        try {
            JSONObject mymaps = new JSONObject();
            JSONArray maplinns = new JSONArray();
            mymaps.put("Map", maplinns);

            jsonMapModul.put(mymaps);

            jsonMap.put("MapModules", jsonMapModul);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }

        mapLineIndex = GetMapSize() -1;
        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    public void showMapByIndex(int nIndex)
    {
        mapLineIndex = nIndex;
        if(mHandler != null)
        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    public int GetMapSize()
    {
        return jsonMapModul.length();
    }

    public void resetAllData()
    {
        mjsonString = "";
        InitMapData();

        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    int nHeight = 0;
    int nWidth = 0;

    int nWorkMode = 0;// 0 绘制背景,1 清除背景,2 绘制地图,3 清除地图,4 显示模式, 5 清除全部,
    // 6 绘制所有线路模式, 7 清除绘制所有线路模式, 8 绘制虚线 , 9 清除虚线

    Paint linePaint;
    Paint backgroundPaint;

    JSONArray jsonBackground;
    JSONArray jsonMapModul;
    JSONArray jsonAlllines;
    JSONArray jsonDotLines;
    JSONObject jsonMapinfo;
    JSONObject jsonMap;

    int xOriginShift = 0;
    int yOriginShift = 0;

    double  scale = 1;
    int linexSeparation = 100;
    int lineySeparation = 100;

    int AutoAttachDistance = 150;


    private void DrawDotLinesMap(Canvas canvas)
    {
        PointToLineDis ptls = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("DotLines");
            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                //old code
                canvas.drawLine(ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, mapDotLinesPaintOnDraw);

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void DrawAllLinesMap(Canvas canvas)
    {
        PointToLineDis ptls = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("AllLines");
            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                //old code
                canvas.drawLine(ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, mapAllLinesPaint);

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public void SaveAllLinesMapDataPart()
    {
        try {
            jsonAlllines = jsonMap.getJSONArray("AllLines");

            JSONObject jsonAdd = new JSONObject();

            JSONObject jsonStart = new JSONObject();
            jsonStart.put("x", attachStartX_AllLines);
            jsonStart.put("y", attachStartY_AllLines);

            JSONObject jsonEnd = new JSONObject();
            jsonEnd.put("x", AutoAttachTargetPointX_AllLines);
            jsonEnd.put("y", AutoAttachTargetPointY_AllLines);

            jsonAdd.put("start", jsonStart);
            jsonAdd.put("end", jsonEnd);

            jsonAlllines.put(jsonAdd);

            jsonMap.put("AllLines", jsonAlllines);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void DrawBackgroundMap(Canvas canvas)
    {
        PointToLineDis ptls = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("Background");
            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                //old code
                canvas.drawLine(ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, backgroundPaint);
/*
                int nDegree = ptls.getDegree(ptStart, ptEnd);

                Bitmap bitmap = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.ic_launcher);

                Paint mypaint = new Paint();
                BitmapShader myBitmapShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);

                Matrix matrix = new Matrix();
                // 设置矩阵变换

                int m = nDegree>90?180-nDegree:nDegree;
                matrix.setTranslate(ptStart.x - bitmap.getWidth(), (float) (ptStart.y +bitmap.getWidth()*Math.abs(Math.sin(m))));
                matrix.preRotate(nDegree);

                Log.i("aaaa", "nDegree :" + nDegree);

                float[] fs = new float[9];
                matrix.getValues(fs);
                Log.d("aaaa", Arrays.toString(fs));

                myBitmapShader.setLocalMatrix(matrix);
                mypaint.setShader(myBitmapShader);

                Rect dest = new Rect();
                dest.left = ptStart.x > ptEnd.x?ptEnd.x:ptStart.x;
                dest.top = ptStart.y>ptEnd.y?ptEnd.y:ptStart.y;
                dest.right = ptStart.x < ptEnd.x?ptEnd.x:ptStart.x;
                dest.bottom = ptStart.y>ptEnd.y?ptStart.y:ptEnd.y;

                mypaint.setStyle(Paint.Style.STROKE);
                mypaint.setStrokeWidth(bitmap.getHeight());
                //mypaint.setStrokeJoin(Paint.Join.ROUND);
                //mypaint.setStrokeCap(Paint.Cap.ROUND);
                mypaint.setAntiAlias(true);

                //canvas.drawRect(dest.left, dest.top, dest.right, dest.top+100, mypaint);
                canvas.drawLine(ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, mypaint);

*/

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        if( nWorkMode == 0)
        {
            DrawRangeonTouchEvent(event);
        }
        else if(nWorkMode == 1)
        {
            ClearRangeonTouchEvent(event);
        }
        else if(nWorkMode == 2)
        {
            DrawLineMaponTouchEvent(event);
        }
        else if(nWorkMode == 3)
        {
            ClearLineMaponTouchEvent(event);
        }
        else if(nWorkMode == 4)
        {
            DisplayMpdeMaponTouchEvent( event);
        }
        else if(nWorkMode == 6)
        {
            DrawAllLinesonTouchEvent( event);
        }
        else if(nWorkMode == 7)
        {
            ClearAllLinesonTouchEvent( event);
        }
        else if(nWorkMode == 8)
        {
            DrawDotLinesonTouchEvent( event);
        }
        else if(nWorkMode == 9)
        {
            ClearDotLinesonTouchEvent( event);
        }

        return true;
    }

    double nLenStart2Touch_displaymode = 0;
    int xStart2TouchPos_displaymode = 0;
    int yStart2TouchPos_displaymode = 0;
    public void DisplayMpdeMaponTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();
        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            xStart2TouchPos_displaymode = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_displaymode = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_displaymode = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_displaymode);
            yOriginShift += (yEnd - yStart2TouchPos_displaymode);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_displaymode)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_displaymode);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_displaymode);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_displaymode = xEnd;
            yStart2TouchPos_displaymode = yEnd;
            nLenStart2Touch_displaymode = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_displaymode);
            yOriginShift += (yEnd - yStart2TouchPos_displaymode);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_displaymode)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_displaymode);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_displaymode);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_displaymode = xEnd;
            yStart2TouchPos_displaymode = yEnd;
            nLenStart2Touch_displaymode = nLenEnd;
        }

    }

    public int mapLineIndex = 0;

    public void DrawCurrentLineMap(Canvas canvas)
    {
        PointToLineDis ptls = new PointToLineDis();
        try {
            jsonMapModul = jsonMap.getJSONArray("MapModules");

            JSONObject objMapLines = jsonMapModul.getJSONObject(mapLineIndex);

            JSONArray ars = objMapLines.getJSONArray("Map");
            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                canvas.drawLine(ptStart.x, ptStart.y, ptEnd.x, ptEnd.y, mapLinePaint);

            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    public void SaveMaplineMapDataPart()
    {
        try {
            jsonMapModul = jsonMap.getJSONArray("MapModules");
            JSONArray jsonMapModulNew = new JSONArray();

            int nLen = jsonMapModul.length();
            for(int i = 0; i < nLen; i ++)
            {
                if(i != mapLineIndex)
                {
                    JSONObject obj = jsonMapModul.getJSONObject(i);
                    jsonMapModulNew.put(obj);
                }
                else
                {
                    JSONObject obj = jsonMapModul.getJSONObject(i);
                    JSONArray lines = obj.getJSONArray("Map");

                    JSONObject jsonAdd = new JSONObject();

                    JSONObject jsonStart = new JSONObject();
                    jsonStart.put("x", attachStartX_mapline);
                    jsonStart.put("y", attachStartY_mapline);

                    JSONObject jsonEnd = new JSONObject();
                    jsonEnd.put("x", AutoAttachTargetPointX_mapline);
                    jsonEnd.put("y", AutoAttachTargetPointY_mapline);

                    jsonAdd.put("start", jsonStart);
                    jsonAdd.put("end", jsonEnd);

                    lines.put(jsonAdd);

                    JSONObject objNewmap = new JSONObject();
                    objNewmap.put("Map", lines);

                    jsonMapModulNew.put(objNewmap);

                }
            }

            jsonMap.put("MapModules", jsonMapModulNew);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    boolean bBeginDraw_DotLines = false;
    int xStart2TouchPos_DotLines = 0;
    int yStart2TouchPos_DotLines = 0;
    double nLenStart2Touch_DotLines = 0;
    boolean bUseAutoAttachTartgetPoint_DotLines = false;
    int xCurPos_DotLines = 0;
    int yCurPos_DotLines = 0;
    int attachStartX_DotLines=0;
    int attachStartY_DotLines=0;
    int AutoAttachTargetPointX_DotLines = -10000;//default
    int AutoAttachTargetPointY_DotLines = -10000;
    private void DrawDotLinesonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();

        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            bBeginDraw_DotLines = false;
            xStart2TouchPos_DotLines = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_DotLines = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_DotLines = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_DotLines);
            yOriginShift += (yEnd - yStart2TouchPos_DotLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_DotLines = false;
            bBeginDraw_DotLines = false;

            if(nLenEnd > nLenStart2Touch_DotLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_DotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_DotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_DotLines = xEnd;
            yStart2TouchPos_DotLines = yEnd;
            nLenStart2Touch_DotLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_DotLines);
            yOriginShift += (yEnd - yStart2TouchPos_DotLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_DotLines = false;
            bBeginDraw_DotLines = false;

            if(nLenEnd > nLenStart2Touch_DotLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_DotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_DotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_DotLines = xEnd;
            yStart2TouchPos_DotLines = yEnd;
            nLenStart2Touch_DotLines = nLenEnd;
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            xCurPos_DotLines = (int)event.getX(0);
            yCurPos_DotLines = (int)event.getY(0);

            if( IsAutoAttachPoint_DotLines(xPos, yPos) == true ) {
                bBeginDraw_DotLines = true;
                bUseAutoAttachTartgetPoint_DotLines = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }else{
                bUseAutoAttachTartgetPoint_DotLines = false;
                bBeginDraw_DotLines = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE && 1 == nCnt)
        {
            xCurPos_DotLines = (int)event.getX(0);
            yCurPos_DotLines = (int)event.getY(0);
            if(bBeginDraw_DotLines == true)
            {
                Point pt = getAutoAttachPoint_bk(xCurPos_DotLines, yCurPos_DotLines);

                if(pt == null)
                {
                    bUseAutoAttachTartgetPoint_DotLines = false;
                    AutoAttachTargetPointX_DotLines = -10000;
                    AutoAttachTargetPointY_DotLines = -10000;

                }else if( pt.x != attachStartX_DotLines || pt.y != attachStartY_DotLines  )
                {
                    bUseAutoAttachTartgetPoint_DotLines = true;
                    AutoAttachTargetPointX_DotLines = pt.x;
                    AutoAttachTargetPointY_DotLines = pt.y;
                }
                else
                {
                    bUseAutoAttachTartgetPoint_DotLines = false;
                    AutoAttachTargetPointX_DotLines = -10000;
                    AutoAttachTargetPointY_DotLines = -10000;
                }

                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP && 1 == nCnt)
        {
            if( bUseAutoAttachTartgetPoint_DotLines == true && bBeginDraw_DotLines == true)
            {
                SaveDotLinesMapDataPart();
            }

            bBeginDraw_DotLines = false;
            bUseAutoAttachTartgetPoint_DotLines = false;
            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
    }

    public void SaveDotLinesMapDataPart()
    {
        try {
            jsonAlllines = jsonMap.getJSONArray("DotLines");

            JSONObject jsonAdd = new JSONObject();

            JSONObject jsonStart = new JSONObject();
            jsonStart.put("x", attachStartX_DotLines);
            jsonStart.put("y", attachStartY_DotLines);

            JSONObject jsonEnd = new JSONObject();
            jsonEnd.put("x", AutoAttachTargetPointX_DotLines);
            jsonEnd.put("y", AutoAttachTargetPointY_DotLines);

            jsonAdd.put("start", jsonStart);
            jsonAdd.put("end", jsonEnd);

            jsonAlllines.put(jsonAdd);

            jsonMap.put("DotLines", jsonAlllines);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    boolean IsAutoAttachPoint_DotLines(int x, int y)
    {
        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;


        int MinPathPointX = 0;
        int MinPathPointY = 0;

        int ndirtX = x-xOrigin;
        if(ndirtX >= 0)
        {
            if( (ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation + 1)*linexSeparation + xOrigin;
                attachStartX_DotLines = (ndirtX)/linexSeparation + 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_DotLines = (ndirtX)/linexSeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation - 1)*linexSeparation + xOrigin;
                attachStartX_DotLines = (ndirtX)/linexSeparation - 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_DotLines = (ndirtX)/linexSeparation;
            }
        }

        int ndirtY = y-yOrigin;
        if(ndirtY>=0)
        {
            if( (ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation + 1)*lineySeparation + yOrigin;
                attachStartY_DotLines = (ndirtY)/lineySeparation + 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_DotLines = (ndirtY)/lineySeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation - 1)*lineySeparation + yOrigin;
                attachStartY_DotLines = (ndirtY)/lineySeparation - 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_DotLines = (ndirtY)/lineySeparation;
            }
        }

        int xlen = MinPathPointX - x;
        int ylen = MinPathPointY - y;

        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

        if(AutoAttachDistance > nLenEnd)
        {
            return true;
        }

        return false;
    }

    boolean bBeginDraw_AllLines = false;
    int xStart2TouchPos_AllLines = 0;
    int yStart2TouchPos_AllLines = 0;
    double nLenStart2Touch_AllLines = 0;
    boolean bUseAutoAttachTartgetPoint_AllLines = false;
    int xCurPos_AllLines = 0;
    int yCurPos_AllLines = 0;
    int attachStartX_AllLines=0;
    int attachStartY_AllLines=0;
    int AutoAttachTargetPointX_AllLines = -10000;//default
    int AutoAttachTargetPointY_AllLines = -10000;
    private void DrawAllLinesonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();

        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            bBeginDraw_AllLines = false;
            xStart2TouchPos_AllLines = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_AllLines = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_AllLines = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_AllLines);
            yOriginShift += (yEnd - yStart2TouchPos_AllLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_AllLines = false;
            bBeginDraw_AllLines = false;

            if(nLenEnd > nLenStart2Touch_AllLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_AllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_AllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_AllLines = xEnd;
            yStart2TouchPos_AllLines = yEnd;
            nLenStart2Touch_AllLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_AllLines);
            yOriginShift += (yEnd - yStart2TouchPos_AllLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_AllLines = false;
            bBeginDraw_AllLines = false;

            if(nLenEnd > nLenStart2Touch_AllLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_AllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_AllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_AllLines = xEnd;
            yStart2TouchPos_AllLines = yEnd;
            nLenStart2Touch_AllLines = nLenEnd;
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            xCurPos_AllLines = (int)event.getX(0);
            yCurPos_AllLines = (int)event.getY(0);

            if( IsAutoAttachPoint_AllLines(xPos, yPos) == true ) {
                bBeginDraw_AllLines = true;
                bUseAutoAttachTartgetPoint_AllLines = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }else{
                bUseAutoAttachTartgetPoint_AllLines = false;
                bBeginDraw_AllLines = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE && 1 == nCnt)
        {
            xCurPos_AllLines = (int)event.getX(0);
            yCurPos_AllLines = (int)event.getY(0);
            if(bBeginDraw_AllLines == true)
            {
                Point pt = getAutoAttachPoint_bk(xCurPos_AllLines, yCurPos_AllLines);

                if(pt == null)
                {
                    bUseAutoAttachTartgetPoint_AllLines = false;
                    AutoAttachTargetPointX_AllLines = -10000;
                    AutoAttachTargetPointY_AllLines = -10000;

                }else if( pt.x != attachStartX_AllLines || pt.y != attachStartY_AllLines  )
                {
                    bUseAutoAttachTartgetPoint_AllLines = true;
                    AutoAttachTargetPointX_AllLines = pt.x;
                    AutoAttachTargetPointY_AllLines = pt.y;
                }
                else
                {
                    bUseAutoAttachTartgetPoint_AllLines = false;
                    AutoAttachTargetPointX_AllLines = -10000;
                    AutoAttachTargetPointY_AllLines = -10000;
                }

                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP && 1 == nCnt)
        {
            if( bUseAutoAttachTartgetPoint_AllLines == true && bBeginDraw_AllLines == true)
            {
                SaveAllLinesMapDataPart();
            }

            bBeginDraw_AllLines = false;
            bUseAutoAttachTartgetPoint_AllLines = false;
            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
    }

    boolean IsAutoAttachPoint_AllLines(int x, int y)
    {
        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;


        int MinPathPointX = 0;
        int MinPathPointY = 0;

        int ndirtX = x-xOrigin;
        if(ndirtX >= 0)
        {
            if( (ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation + 1)*linexSeparation + xOrigin;
                attachStartX_AllLines = (ndirtX)/linexSeparation + 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_AllLines = (ndirtX)/linexSeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation - 1)*linexSeparation + xOrigin;
                attachStartX_AllLines = (ndirtX)/linexSeparation - 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_AllLines = (ndirtX)/linexSeparation;
            }
        }

        int ndirtY = y-yOrigin;
        if(ndirtY>=0)
        {
            if( (ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation + 1)*lineySeparation + yOrigin;
                attachStartY_AllLines = (ndirtY)/lineySeparation + 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_AllLines = (ndirtY)/lineySeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation - 1)*lineySeparation + yOrigin;
                attachStartY_AllLines = (ndirtY)/lineySeparation - 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_AllLines = (ndirtY)/lineySeparation;
            }
        }

        int xlen = MinPathPointX - x;
        int ylen = MinPathPointY - y;

        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

        if(AutoAttachDistance > nLenEnd)
        {
            return true;
        }

        return false;
    }

    boolean bBeginDraw_mapline = false;
    int xStart2TouchPos_mapline = 0;
    int yStart2TouchPos_mapline = 0;
    double nLenStart2Touch_mapline = 0;
    boolean bUseAutoAttachTartgetPoint_mapline = false;
    int xCurPos_mapline = 0;
    int yCurPos_mapline = 0;
    int attachStartX_mapline=0;
    int attachStartY_mapline=0;
    int AutoAttachTargetPointX_mapline = -10000;//default
    int AutoAttachTargetPointY_mapline = -10000;
    private void DrawLineMaponTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();

        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            bBeginDraw_mapline = false;
            xStart2TouchPos_mapline = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_mapline = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_mapline = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_mapline);
            yOriginShift += (yEnd - yStart2TouchPos_mapline);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_mapline = false;
            bBeginDraw_mapline = false;

            if(nLenEnd > nLenStart2Touch_mapline)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_mapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_mapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_mapline = xEnd;
            yStart2TouchPos_mapline = yEnd;
            nLenStart2Touch_mapline = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_mapline);
            yOriginShift += (yEnd - yStart2TouchPos_mapline);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_mapline = false;
            bBeginDraw_mapline = false;

            if(nLenEnd > nLenStart2Touch_mapline)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_mapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_mapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_mapline = xEnd;
            yStart2TouchPos_mapline = yEnd;
            nLenStart2Touch_mapline = nLenEnd;
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            xCurPos_mapline = (int)event.getX(0);
            yCurPos_mapline = (int)event.getY(0);

            if( IsAutoAttachPoint_mapline(xPos, yPos) == true ) {
                bBeginDraw_mapline = true;
                bUseAutoAttachTartgetPoint_mapline = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }else{
                bUseAutoAttachTartgetPoint_mapline = false;
                bBeginDraw_mapline = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE && 1 == nCnt)
        {
            xCurPos_mapline = (int)event.getX(0);
            yCurPos_mapline = (int)event.getY(0);
            if(bBeginDraw_mapline == true)
            {
                Point pt = getAutoAttachPoint_bk(xCurPos_mapline, yCurPos_mapline);

                if(pt == null)
                {
                    bUseAutoAttachTartgetPoint_mapline = false;
                    AutoAttachTargetPointX_mapline = -10000;
                    AutoAttachTargetPointY_mapline = -10000;

                }else if( pt.x != attachStartX_mapline || pt.y != attachStartY_mapline  )
                {
                    bUseAutoAttachTartgetPoint_mapline = true;
                    AutoAttachTargetPointX_mapline = pt.x;
                    AutoAttachTargetPointY_mapline = pt.y;
                }
                else
                {
                    bUseAutoAttachTartgetPoint_mapline = false;
                    AutoAttachTargetPointX_mapline = -10000;
                    AutoAttachTargetPointY_mapline = -10000;
                }

                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP && 1 == nCnt)
        {
            if( bUseAutoAttachTartgetPoint_mapline == true && bBeginDraw_mapline == true)
            {
                SaveMaplineMapDataPart();
            }

            bBeginDraw_mapline = false;
            bUseAutoAttachTartgetPoint_mapline = false;
            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
    }

    private void DrawAttachLine_bk(Canvas canvas)
    {
        Point pt = CoordinateToPointxy(attachStartX_bk, attachStartY_bk);

        if( bUseAutoAttachTartgetPoint_bk == true)
        {
            Point ptTarget = CoordinateToPointxy(AutoAttachTargetPointX_bk, AutoAttachTargetPointY_bk);
            canvas.drawLine(pt.x, pt.y, ptTarget.x, ptTarget.y, backgroundPaint);
        }
        else {
            canvas.drawLine(pt.x, pt.y, xCurPos_bk, yCurPos_bk, backgroundPaint);
        }

        canvas.drawCircle(pt.x, pt.y, 10, backgroundPaint);
    }


    private void DrawAttachLine_Dotlines(Canvas canvas)
    {
        Point pt = CoordinateToPointxy(attachStartX_DotLines, attachStartY_DotLines);

        if( bUseAutoAttachTartgetPoint_DotLines == true)
        {
            Point ptTarget = CoordinateToPointxy(AutoAttachTargetPointX_DotLines, AutoAttachTargetPointY_DotLines);
            canvas.drawLine(pt.x, pt.y, ptTarget.x, ptTarget.y, mapDotLinesPaint);
        }
        else {
            canvas.drawLine(pt.x, pt.y, xCurPos_DotLines, yCurPos_DotLines, mapDotLinesPaint);
        }

        canvas.drawCircle(pt.x, pt.y, 10, mapDotLinesPaint);
    }

    private void DrawAttachLine_Alllines(Canvas canvas)
    {
        Point pt = CoordinateToPointxy(attachStartX_AllLines, attachStartY_AllLines);

        if( bUseAutoAttachTartgetPoint_AllLines == true)
        {
            Point ptTarget = CoordinateToPointxy(AutoAttachTargetPointX_AllLines, AutoAttachTargetPointY_AllLines);
            canvas.drawLine(pt.x, pt.y, ptTarget.x, ptTarget.y, mapAllLinesPaint);
        }
        else {
            canvas.drawLine(pt.x, pt.y, xCurPos_AllLines, yCurPos_AllLines, mapAllLinesPaint);
        }

        canvas.drawCircle(pt.x, pt.y, 10, mapAllLinesPaint);
    }

    private void DrawAttachLine_mapline(Canvas canvas)
    {
        Point pt = CoordinateToPointxy(attachStartX_mapline, attachStartY_mapline);

        if( bUseAutoAttachTartgetPoint_mapline == true)
        {
            Point ptTarget = CoordinateToPointxy(AutoAttachTargetPointX_mapline, AutoAttachTargetPointY_mapline);
            canvas.drawLine(pt.x, pt.y, ptTarget.x, ptTarget.y, mapLinePaint);
        }
        else {
            canvas.drawLine(pt.x, pt.y, xCurPos_mapline, yCurPos_mapline, mapLinePaint);
        }

        canvas.drawCircle(pt.x, pt.y, 10, mapLinePaint);
    }

    private Point CoordinateToPointxy(int x, int y)
    {
        Point pt = new Point(0,0);

        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;

        pt.x = xOrigin + x*linexSeparation;
        pt.y = yOrigin + y*lineySeparation;

        return pt;
    }

    public final static int MIN_LENGTH = 50;
    public final static int MAX_LENGTH = 200;
    public void DrawBackgroundLine(Canvas canvas)
    {
        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;

        int yStart = 0;

        if( Math.abs(scale - 1.0) >= 0.01 )
        {
            lineySeparation = (int)((double)lineySeparation * scale);
            linexSeparation = (int)((double)linexSeparation * scale);

            if(lineySeparation<MIN_LENGTH)
            {
                lineySeparation = MIN_LENGTH;
            }

            if(lineySeparation>MAX_LENGTH)
            {
                lineySeparation = MAX_LENGTH;
            }

            if(linexSeparation<MIN_LENGTH)
            {
                linexSeparation = MIN_LENGTH;
            }

            if(linexSeparation>MAX_LENGTH)
            {
                linexSeparation = MAX_LENGTH;
            }
        }

        if(yOrigin >= 0 )
        {
            yStart = yOrigin % lineySeparation;

        }else
        {
            yStart =  lineySeparation - Math.abs(yOrigin)%lineySeparation;
        }

        Path mPath = new Path();
        mPath.moveTo(0, yStart);
        mPath.quadTo(nWidth/2, yStart, nWidth, yStart);
        canvas.drawPath(mPath, linePaint);

        int yPos = yStart + lineySeparation;
        while(yPos <= nHeight)
        {
            mPath = new Path();
            mPath.moveTo(0, yPos);
            mPath.quadTo(nWidth/2, yPos, nWidth, yPos);
            canvas.drawPath(mPath, linePaint);
            yPos += lineySeparation;
        }

        int xStart = 0;
        if(xOrigin >= 0 )
        {
            xStart = xOrigin%linexSeparation;
        }else
        {
            xStart =  lineySeparation - Math.abs(xOrigin)%lineySeparation;
        }
        mPath = new Path();
        mPath.moveTo(xStart, 0);
        mPath.quadTo(xStart, nHeight/2, xStart, nHeight);
        canvas.drawPath(mPath, linePaint);

        int xPos = xStart + linexSeparation;
        while(xPos <= nWidth)
        {
            mPath = new Path();
            mPath.moveTo(xPos, 0);
            mPath.quadTo(xPos, nHeight/2, xPos, nHeight);
            canvas.drawPath(mPath, linePaint);
            xPos += linexSeparation;
        }
    }

    double nLenStart2Touch_clearmapline = 0;
    int xStart2TouchPos_clearmapline = 0;
    int yStart2TouchPos_clearmapline = 0;
    public void ClearLineMaponTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();
        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            xStart2TouchPos_clearmapline = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_clearmapline = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_clearmapline = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearmapline);
            yOriginShift += (yEnd - yStart2TouchPos_clearmapline);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearmapline)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearmapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearmapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearmapline = xEnd;
            yStart2TouchPos_clearmapline = yEnd;
            nLenStart2Touch_clearmapline = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearmapline);
            yOriginShift += (yEnd - yStart2TouchPos_clearmapline);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearmapline)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearmapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearmapline);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearmapline = xEnd;
            yStart2TouchPos_clearmapline = yEnd;
            nLenStart2Touch_clearmapline = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            CheckClearMapLines(xPos, yPos);
        }
    }

    public void CheckClearMapLines(int x, int y)
    {
        PointToLineDis ptl = new PointToLineDis();
        try {
            jsonMapModul = jsonMap.getJSONArray("MapModules");

            JSONArray jsonMapModulNew = new JSONArray();

            for(int i = 0; i < jsonMapModul.length(); i ++)
            {
                JSONObject objMapLines = jsonMapModul.getJSONObject(i);
                if( i == mapLineIndex)
                {
                    JSONArray ars = objMapLines.getJSONArray("Map");

                    JSONArray newars = new JSONArray();
                    int nLen = ars.length();

                    for(int j = 0; j < nLen; j ++)
                    {
                        JSONObject obj = ars.getJSONObject(j);

                        JSONObject start = obj.getJSONObject("start");
                        JSONObject end = obj.getJSONObject("end");
                        int nStartX = start.getInt("x");
                        int nStartY = start.getInt("y");
                        int nEndX = end.getInt("x");
                        int nEndY = end.getInt("y");

                        Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                        Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                        double bLen = ptl.alSegmentDis(x, y, ptStart, ptEnd);
                        if( bLen > CLEAR_DISTANCE )
                        {
                            JSONObject jsonAdd = new JSONObject();

                            JSONObject jsonStart = new JSONObject();
                            jsonStart.put("x", nStartX);
                            jsonStart.put("y", nStartY);

                            JSONObject jsonEnd = new JSONObject();
                            jsonEnd.put("x", nEndX);
                            jsonEnd.put("y", nEndY);

                            jsonAdd.put("start", jsonStart);
                            jsonAdd.put("end", jsonEnd);

                            newars.put(jsonAdd);
                        }
                    }

                    JSONObject newmap = new JSONObject();
                    newmap.put("Map", newars);

                    jsonMapModulNew.put(newmap);

                }
                else
                {
                    jsonMapModulNew.put(objMapLines);
                }
            }

            jsonMap.put("MapModules", jsonMapModulNew);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }

        mHandler.sendEmptyMessage(MSG_INVALIDATE);

    }


    double nLenStart2Touch_clearDotLines = 0;
    int xStart2TouchPos_clearDotLines = 0;
    int yStart2TouchPos_clearDotLines = 0;
    public void ClearDotLinesonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();
        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            xStart2TouchPos_clearDotLines = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_clearDotLines = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_clearDotLines = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearDotLines);
            yOriginShift += (yEnd - yStart2TouchPos_clearDotLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearDotLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearDotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearDotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearDotLines = xEnd;
            yStart2TouchPos_clearDotLines = yEnd;
            nLenStart2Touch_clearDotLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearDotLines);
            yOriginShift += (yEnd - yStart2TouchPos_clearDotLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearDotLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearDotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearDotLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearDotLines = xEnd;
            yStart2TouchPos_clearDotLines = yEnd;
            nLenStart2Touch_clearDotLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            CheckClearDotLines(xPos, yPos);
        }
    }

    public void CheckClearDotLines(int x, int y)
    {
        PointToLineDis ptl = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("DotLines");

            JSONArray newars = new JSONArray();

            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                double bLen = ptl.alSegmentDis(x, y, ptStart, ptEnd);
                if( bLen > CLEAR_DISTANCE )
                {
                    JSONObject jsonAdd = new JSONObject();

                    JSONObject jsonStart = new JSONObject();
                    jsonStart.put("x", nStartX);
                    jsonStart.put("y", nStartY);

                    JSONObject jsonEnd = new JSONObject();
                    jsonEnd.put("x", nEndX);
                    jsonEnd.put("y", nEndY);

                    jsonAdd.put("start", jsonStart);
                    jsonAdd.put("end", jsonEnd);

                    newars.put(jsonAdd);
                }
            }

            jsonMap.put("DotLines", newars);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    double nLenStart2Touch_clearAllLines = 0;
    int xStart2TouchPos_clearAllLines = 0;
    int yStart2TouchPos_clearAllLines = 0;
    public void ClearAllLinesonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();
        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            xStart2TouchPos_clearAllLines = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_clearAllLines = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_clearAllLines = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearAllLines);
            yOriginShift += (yEnd - yStart2TouchPos_clearAllLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearAllLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearAllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearAllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearAllLines = xEnd;
            yStart2TouchPos_clearAllLines = yEnd;
            nLenStart2Touch_clearAllLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearAllLines);
            yOriginShift += (yEnd - yStart2TouchPos_clearAllLines);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearAllLines)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearAllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearAllLines);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearAllLines = xEnd;
            yStart2TouchPos_clearAllLines = yEnd;
            nLenStart2Touch_clearAllLines = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            CheckClearAllLines(xPos, yPos);
        }
    }

    public void CheckClearAllLines(int x, int y)
    {
        PointToLineDis ptl = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("AllLines");

            JSONArray newars = new JSONArray();

            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                double bLen = ptl.alSegmentDis(x, y, ptStart, ptEnd);
                if( bLen > CLEAR_DISTANCE )
                {
                    JSONObject jsonAdd = new JSONObject();

                    JSONObject jsonStart = new JSONObject();
                    jsonStart.put("x", nStartX);
                    jsonStart.put("y", nStartY);

                    JSONObject jsonEnd = new JSONObject();
                    jsonEnd.put("x", nEndX);
                    jsonEnd.put("y", nEndY);

                    jsonAdd.put("start", jsonStart);
                    jsonAdd.put("end", jsonEnd);

                    newars.put(jsonAdd);
                }
            }

            jsonMap.put("AllLines", newars);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    double nLenStart2Touch_clearbk = 0;
    int xStart2TouchPos_clearbk = 0;
    int yStart2TouchPos_clearbk = 0;
    public void ClearRangeonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();
        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            xStart2TouchPos_clearbk = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_clearbk = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_clearbk = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearbk);
            yOriginShift += (yEnd - yStart2TouchPos_clearbk);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearbk)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearbk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearbk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearbk = xEnd;
            yStart2TouchPos_clearbk = yEnd;
            nLenStart2Touch_clearbk = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_clearbk);
            yOriginShift += (yEnd - yStart2TouchPos_clearbk);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            if(nLenEnd > nLenStart2Touch_clearbk)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearbk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_clearbk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            xStart2TouchPos_clearbk = xEnd;
            yStart2TouchPos_clearbk = yEnd;
            nLenStart2Touch_clearbk = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            CheckClearLine(xPos, yPos);
        }

    }

    int CLEAR_DISTANCE = 20;
    public void CheckClearLine(int x, int y)
    {
        PointToLineDis ptl = new PointToLineDis();
        try {
            JSONArray ars = jsonMap.getJSONArray("Background");

            JSONArray newars = new JSONArray();

            int nLen = ars.length();
            for(int i = 0; i < nLen; i ++)
            {
                JSONObject obj = ars.getJSONObject(i);

                JSONObject start = obj.getJSONObject("start");
                JSONObject end = obj.getJSONObject("end");
                int nStartX = start.getInt("x");
                int nStartY = start.getInt("y");
                int nEndX = end.getInt("x");
                int nEndY = end.getInt("y");

                Point ptStart = CoordinateToPointxy(nStartX, nStartY);
                Point ptEnd = CoordinateToPointxy(nEndX, nEndY);

                double bLen = ptl.alSegmentDis(x, y, ptStart, ptEnd);
                if( bLen > CLEAR_DISTANCE )
                {
                    JSONObject jsonAdd = new JSONObject();

                    JSONObject jsonStart = new JSONObject();
                    jsonStart.put("x", nStartX);
                    jsonStart.put("y", nStartY);

                    JSONObject jsonEnd = new JSONObject();
                    jsonEnd.put("x", nEndX);
                    jsonEnd.put("y", nEndY);

                    jsonAdd.put("start", jsonStart);
                    jsonAdd.put("end", jsonEnd);

                    newars.put(jsonAdd);
                }
            }

            jsonMap.put("Background", newars);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        mHandler.sendEmptyMessage(MSG_INVALIDATE);
    }

    boolean bBeginDraw_bk = false;
    int xStart2TouchPos_bk = 0;
    int yStart2TouchPos_bk = 0;
    double nLenStart2Touch_bk = 0;
    boolean bUseAutoAttachTartgetPoint_bk = false;
    int xCurPos_bk = 0;
    int yCurPos_bk = 0;
    int attachStartX_bk=0;
    int attachStartY_bk=0;
    int AutoAttachTargetPointX_bk = -10000;//default
    int AutoAttachTargetPointY_bk = -10000;

    public void DrawRangeonTouchEvent(MotionEvent event)
    {
        int nCnt = event.getPointerCount();
        int n = event.getAction();

        if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            bBeginDraw_bk = false;
            xStart2TouchPos_bk = ((int)event.getX(0) + (int)event.getX(1))/2;
            yStart2TouchPos_bk = ((int)event.getY(0) + (int)event.getY(1))/2;

            nLenStart2Touch_bk = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_bk);
            yOriginShift += (yEnd - yStart2TouchPos_bk);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_bk = false;
            bBeginDraw_bk = false;

            if(nLenEnd > nLenStart2Touch_bk)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_bk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_bk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            Log.i("aaaa", "scale : " + scale);

            xStart2TouchPos_bk = xEnd;
            yStart2TouchPos_bk = yEnd;
            nLenStart2Touch_bk = nLenEnd;
        }
        else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE  && 2 == nCnt)
        {
            int xlen = Math.abs((int)event.getX(0) - (int)event.getX(1));
            int ylen = Math.abs((int)event.getY(0) - (int)event.getY(1));

            int xEnd = ((int)event.getX(0) + (int)event.getX(1))/2;
            int yEnd = ((int)event.getY(0) + (int)event.getY(1))/2;

            xOriginShift += (xEnd - xStart2TouchPos_bk);
            yOriginShift += (yEnd - yStart2TouchPos_bk);

            double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

            bUseAutoAttachTartgetPoint_bk = false;
            bBeginDraw_bk = false;

            if(nLenEnd > nLenStart2Touch_bk)
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_bk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
            else
            {
                scale = Math.sqrt(nLenEnd/nLenStart2Touch_bk);
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }

            Log.i("aaaa", "scale : " + scale);

            xStart2TouchPos_bk = xEnd;
            yStart2TouchPos_bk = yEnd;
            nLenStart2Touch_bk = nLenEnd;
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_DOWN && 1 == nCnt)
        {
            int xPos = (int)event.getX(0);
            int yPos = (int)event.getY(0);

            xCurPos_bk = (int)event.getX(0);
            yCurPos_bk = (int)event.getY(0);

            if( IsAutoAttachPoint_bk(xPos, yPos) == true ) {
                bBeginDraw_bk = true;
                bUseAutoAttachTartgetPoint_bk = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }else{
                bUseAutoAttachTartgetPoint_bk = false;
                bBeginDraw_bk = false;
                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_MOVE && 1 == nCnt)
        {
            xCurPos_bk = (int)event.getX(0);
            yCurPos_bk = (int)event.getY(0);
            if(bBeginDraw_bk == true)
            {
                Point pt = getAutoAttachPoint_bk(xCurPos_bk, yCurPos_bk);

                if(pt == null)
                {
                    bUseAutoAttachTartgetPoint_bk = false;
                    AutoAttachTargetPointX_bk = -10000;
                    AutoAttachTargetPointY_bk = -10000;

                }else if( pt.x != attachStartX_bk || pt.y != attachStartY_bk  )
                {
                    bUseAutoAttachTartgetPoint_bk = true;
                    AutoAttachTargetPointX_bk = pt.x;
                    AutoAttachTargetPointY_bk = pt.y;
                }
                else
                {
                    bUseAutoAttachTartgetPoint_bk = false;
                    AutoAttachTargetPointX_bk = -10000;
                    AutoAttachTargetPointY_bk = -10000;
                }

                mHandler.sendEmptyMessage(MSG_INVALIDATE);
            }
        }else if( (event.getAction()&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP && 1 == nCnt)
        {
            if( bUseAutoAttachTartgetPoint_bk == true && bBeginDraw_bk == true)
            {
                SaveBackgriundMapDataPart();
            }

            bBeginDraw_bk = false;
            bUseAutoAttachTartgetPoint_bk = false;
            mHandler.sendEmptyMessage(MSG_INVALIDATE);
        }
    }

    public void SaveBackgriundMapDataPart()
    {
        try {
            jsonBackground = jsonMap.getJSONArray("Background");

            JSONObject jsonAdd = new JSONObject();

            JSONObject jsonStart = new JSONObject();
            jsonStart.put("x", attachStartX_bk);
            jsonStart.put("y", attachStartY_bk);

            JSONObject jsonEnd = new JSONObject();
            jsonEnd.put("x", AutoAttachTargetPointX_bk);
            jsonEnd.put("y", AutoAttachTargetPointY_bk);

            jsonAdd.put("start", jsonStart);
            jsonAdd.put("end", jsonEnd);

            jsonBackground.put(jsonAdd);

            jsonMap.put("Background", jsonBackground);

            Log.i("aaaa", jsonMap.toString());

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    Point getAutoAttachPoint_bk(int x, int y)
    {
        Point poit = null;

        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;
        int attachX = 0;
        int attachY = 0;
        int myMinPathPointX = 0;
        int myMinPathPointY = 0;

        int ndirtX = x-xOrigin;
        if(ndirtX >= 0)
        {
            if( (ndirtX)%linexSeparation > linexSeparation/2)
            {
                myMinPathPointX = ((ndirtX)/linexSeparation + 1)*linexSeparation + xOrigin;
                attachX = (ndirtX)/linexSeparation + 1;
            }
            else
            {
                myMinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachX = (ndirtX)/linexSeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtX)%linexSeparation > linexSeparation/2)
            {
                myMinPathPointX = ((ndirtX)/linexSeparation - 1)*linexSeparation + xOrigin;
                attachX = (ndirtX)/linexSeparation - 1;
            }
            else
            {
                myMinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachX = (ndirtX)/linexSeparation;
            }
        }

        int ndirtY = y-yOrigin;
        if(ndirtY>=0)
        {
            if( (ndirtY)%lineySeparation > lineySeparation/2)
            {
                myMinPathPointY = ((ndirtY)/lineySeparation + 1)*lineySeparation + yOrigin;
                attachY = (ndirtY)/lineySeparation + 1;
            }
            else
            {
                myMinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachY = (ndirtY)/lineySeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtY)%lineySeparation > lineySeparation/2)
            {
                myMinPathPointY = ((ndirtY)/lineySeparation - 1)*lineySeparation + yOrigin;
                attachY = (ndirtY)/lineySeparation - 1;
            }
            else
            {
                myMinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachY = (ndirtY)/lineySeparation;
            }
        }

        int xlen = myMinPathPointX - x;
        int ylen = myMinPathPointY - y;

        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

        if(AutoAttachDistance > nLenEnd)
        {
            poit = new Point(attachX,attachY);
        }

        return poit;
    }

    boolean IsAutoAttachPoint_mapline(int x, int y)
    {
        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;


        int MinPathPointX = 0;
        int MinPathPointY = 0;

        int ndirtX = x-xOrigin;
        if(ndirtX >= 0)
        {
            if( (ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation + 1)*linexSeparation + xOrigin;
                attachStartX_mapline = (ndirtX)/linexSeparation + 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_mapline = (ndirtX)/linexSeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation - 1)*linexSeparation + xOrigin;
                attachStartX_mapline = (ndirtX)/linexSeparation - 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_mapline = (ndirtX)/linexSeparation;
            }
        }

        int ndirtY = y-yOrigin;
        if(ndirtY>=0)
        {
            if( (ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation + 1)*lineySeparation + yOrigin;
                attachStartY_mapline = (ndirtY)/lineySeparation + 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_mapline = (ndirtY)/lineySeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation - 1)*lineySeparation + yOrigin;
                attachStartY_mapline = (ndirtY)/lineySeparation - 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_mapline = (ndirtY)/lineySeparation;
            }
        }

        int xlen = MinPathPointX - x;
        int ylen = MinPathPointY - y;

        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

        if(AutoAttachDistance > nLenEnd)
        {
            return true;
        }

        return false;
    }

    boolean IsAutoAttachPoint_bk(int x, int y)
    {
        int xOrigin = nWidth/2 + xOriginShift;
        int yOrigin = nHeight/2 + yOriginShift;


        int MinPathPointX = 0;
        int MinPathPointY = 0;

        int ndirtX = x-xOrigin;
        if(ndirtX >= 0)
        {
            if( (ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation + 1)*linexSeparation + xOrigin;
                attachStartX_bk = (ndirtX)/linexSeparation + 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_bk = (ndirtX)/linexSeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtX)%linexSeparation > linexSeparation/2)
            {
                MinPathPointX = ((ndirtX)/linexSeparation - 1)*linexSeparation + xOrigin;
                attachStartX_bk = (ndirtX)/linexSeparation - 1;
            }
            else
            {
                MinPathPointX = (ndirtX)/linexSeparation*linexSeparation + xOrigin;
                attachStartX_bk = (ndirtX)/linexSeparation;
            }
        }

        int ndirtY = y-yOrigin;
        if(ndirtY>=0)
        {
            if( (ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation + 1)*lineySeparation + yOrigin;
                attachStartY_bk = (ndirtY)/lineySeparation + 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_bk = (ndirtY)/lineySeparation;
            }
        }
        else
        {
            if( Math.abs(ndirtY)%lineySeparation > lineySeparation/2)
            {
                MinPathPointY = ((ndirtY)/lineySeparation - 1)*lineySeparation + yOrigin;
                attachStartY_bk = (ndirtY)/lineySeparation - 1;
            }
            else
            {
                MinPathPointY = (ndirtY)/lineySeparation*lineySeparation + yOrigin;
                attachStartY_bk = (ndirtY)/lineySeparation;
            }
        }

        int xlen = MinPathPointX - x;
        int ylen = MinPathPointY - y;

        double nLenEnd = Math.sqrt((double)xlen*xlen + (double)ylen * ylen);

        if(AutoAttachDistance > nLenEnd)
        {
            return true;
        }

        return false;
    }

    Paint mapLinePaint;
    public void initMapLinePaint()
    {
        BlurMaskFilter filter = new BlurMaskFilter(10,
                BlurMaskFilter.Blur.SOLID);

        mapLinePaint = new Paint();
        mapLinePaint.setColor(Color.rgb(89,171,240));
        mapLinePaint.setStrokeJoin(Paint.Join.ROUND);
        mapLinePaint.setStrokeCap(Paint.Cap.ROUND);
        mapLinePaint.setAntiAlias(true);
        mapLinePaint.setStrokeWidth((float) 15.0);

        mapLinePaint.setMaskFilter(filter);
    }

    Paint mapDotLinesPaintOnDraw;
    Paint mapDotLinesPaint;
    public void initDotLinesPaint()
    {
        mapDotLinesPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mapDotLinesPaint.setStyle(Paint.Style.STROKE);
        mapDotLinesPaint.setColor(Color.RED);
        mapDotLinesPaint.setStrokeWidth(2);
        PathEffect effects = new DashPathEffect(new float[]{12, 8, 12, 8}, 0);
        mapDotLinesPaint.setPathEffect(effects);

        mapDotLinesPaintOnDraw = new Paint(Paint.ANTI_ALIAS_FLAG);
        mapDotLinesPaintOnDraw.setStyle(Paint.Style.STROKE);
        mapDotLinesPaintOnDraw.setColor(Color.BLUE);
        mapDotLinesPaintOnDraw.setStrokeWidth(2);
        mapDotLinesPaintOnDraw.setPathEffect(effects);
    }

    Paint mapAllLinesPaint;
    public void initAlllinesePaint()
    {
        mapAllLinesPaint = new Paint();
        mapAllLinesPaint.setColor(Color.rgb(70,74,81));
        mapAllLinesPaint.setStrokeJoin(Paint.Join.ROUND);
        mapAllLinesPaint.setStrokeCap(Paint.Cap.ROUND);
        mapAllLinesPaint.setAntiAlias(true);
        mapAllLinesPaint.setStrokeWidth((float) 10.0);
    }

    public void initLinePaint()
    {
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setColor(Color.WHITE);
        linePaint.setStrokeWidth(1);
        PathEffect effects = new DashPathEffect(new float[]{12, 8, 12, 8}, 0);
        linePaint.setPathEffect(effects);
    }

    Bitmap mBmpBackground_map;     //整个背景

    public void initBackgroundPaint()
    {
        backgroundPaint = new Paint();
        backgroundPaint.setColor(Color.rgb(27,34,39));
        backgroundPaint.setStrokeWidth((float) 20.0);
        backgroundPaint.setAntiAlias(true);
        backgroundPaint.setStrokeCap(Paint.Cap.ROUND);
        backgroundPaint.setStyle(Paint.Style.STROKE);


        Resources res = getResources();
        mBmpBackground_map= BitmapFactory.decodeResource(res, R.mipmap.background);
    }

    public void DrawOriginPoint(Canvas canvas, int x, int y)
    {
        Paint p = new Paint();
        p.setColor(Color.RED);

        int xOrigin = nWidth/2;
        int yOrigin = nHeight/2;

        canvas.drawCircle(x, y, 10, p);
    }


}
